package com.luyuan.crm.sale.web;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.faces.model.DataModel;
import javax.faces.model.SelectItem;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.luyuan.crm.member.model.Region;
import com.luyuan.crm.member.service.RegionService;
import com.luyuan.crm.sale.model.ExpressCompany;
import com.luyuan.crm.sale.model.Order;
import com.luyuan.crm.sale.model.OrderStatus;
import com.luyuan.crm.sale.model.OrderType;
import com.luyuan.crm.sale.model.PaymentType;
import com.luyuan.crm.sale.service.OrderService;
import com.luyuan.crm.sale.util.CityUtil;
import com.luyuan.crm.util.ExcelUtil;
import com.ruijie.foundation.query.Page;
import com.ruijie.foundation.query.criteria.CriteriaTemplate;
import com.ruijie.foundation.query.criteria.RestrictionTemplate;
import com.ruijie.util.StringUtils;
import com.ruijie.web.jsf.action.BaseAction;
import com.ruijie.web.jsf.context.TableContext;
import com.ruijie.web.jsf.model.PageDataModel;
import com.ruijie.web.jsf.model.TableOrder;
import com.ruijie.web.jsf.model.TablePage;
import com.ruijie.web.jsf.provider.SelectItemsProvider;

@Component("orderStorageAction")
@Scope("view")
public class OrderStorageAction extends BaseAction implements InitializingBean, SelectItemsProvider {

    @Resource(name = "orderService")
    private OrderService orderService;

    @Resource(name = "regionService")
    private RegionService regionService;

    private Order order = null;

    private String uuid = null;

    private OrderStatus orderStatus = OrderStatus.VERIFIED;

    private String remarks;

    private ExpressCompany expressCompany;

    private Date startDate;

    private Date endDate;

    public void deliverOrder() {
        if (order.getOrderStatus() == OrderStatus.DELIVERED) {
            orderService.changeExpressOrder(order, remarks);
        }
        else if (order.getOrderStatus() == OrderStatus.VERIFIED) {
            orderService.deliverOrder(order, remarks);
        }
    }

    public void returnOrder() {
        orderService.returnOrder(order, remarks);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (getRequestParameter("uuid") != null && order == null) {
            String id = getRequestParameter("uuid");
            order = orderService.getById(id);
        }
    }

    public DataModel getOrderTableModel() {
        TablePage tablePage = TableContext.getTablePage();
        List<TableOrder> tableOrders = TableContext.getTableOrders();
        List<org.hibernate.criterion.Order> orders = new ArrayList<org.hibernate.criterion.Order>();
        for (TableOrder tableOrder : tableOrders) {
            org.hibernate.criterion.Order order = tableOrder.toOrder();
            if (order != null) {
                orders.add(order);
            }
        }

        if (orderStatus != OrderStatus.DELIVERED && orderStatus != OrderStatus.VERIFIED) {
            return new PageDataModel(new Page(1, 1, tablePage.getPageSize(), new ArrayList<Object>()));
        }

        CriteriaTemplate c = getCriterialTemplate();

        Page page = orderService.pagedQuery(c, tablePage.getPage(), tablePage.getPageSize(), orders);
        return new PageDataModel(page);
    }

    private CriteriaTemplate getCriterialTemplate() {
        CriteriaTemplate c = CriteriaTemplate.forClass(Order.class);
        RestrictionTemplate r = new RestrictionTemplate(false);

        c.add(r.eq("orderStatus", orderStatus));
        if (StringUtils.isNotEmpty(uuid)) {
            c.add(r.eq("id", uuid));
        }

        if (startDate != null && endDate == null) {
            c.add(r.gt("createTime", startDate));
        }
        else if (startDate == null && endDate != null) {
            c.add(r.lt("createTime", endDate));
        }
        else if (startDate != null && endDate != null) {
            c.add(r.between("createTime", startDate, endDate));
        }

        if (expressCompany != null) {
            c.createCriteria("delivery", "d").add(r.eq("d.expressCompany", expressCompany));
        }

        return c;
    }

    public void exportSFExcel() throws IOException {
        List<Order> orders = getExportData();

        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet = ExcelUtil.createSheet(wb, "销售记录");
        sheet.setDisplayGridlines(true);

        ExcelUtil.mergeCell(sheet, 0, (short) 0, 2, (short) 0);
        HSSFCell cell = sheet.createRow(0).createCell((short) 0);
        cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
        cell.setCellValue(new HSSFRichTextString("序\n号"));

        ExcelUtil.mergeCell(sheet, 0, (short) 1, 0, (short) 5);
        cell = sheet.createRow(0).createCell((short) 1);
        cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
        cell.setCellValue(new HSSFRichTextString("收件方信息"));

        ExcelUtil.mergeCell(sheet, 0, (short) 6, 0, (short) 15);
        cell = sheet.createRow(0).createCell((short) 6);
        cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
        cell.setCellValue(new HSSFRichTextString("运单其他信息"));

        String[] headers = { "收件公司", "联系人", "联系电话", "手机号码", "收件详细地址", "付款方式", "托寄物内容", "托寄物数量", "件数", "寄方客户备注",
                "是否代收货款", "代收货款金额", "是否保价", "保价金额", "是否自取" };
        for (short i = 1; i < 16; i++) {
            ExcelUtil.mergeCell(sheet, 1, i, 2, i);
            cell = sheet.createRow(1).createCell(i);
            cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
            cell.setCellValue(new HSSFRichTextString(headers[i - 1]));
        }
        for (short i = 0; i < 16; i++) {
            sheet.createRow(2).createCell(i).setCellStyle(ExcelUtil.getNormalCellStyle(wb));
        }
        sheet.createFreezePane(0, 3);

        int len = orders.size();
        for (int i = 0; i < len; i++) {
            Order o = orders.get(i);
            HSSFRow row = sheet.createRow(i + 3);

            cell = row.createCell((short) 0);
            cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
            cell.setCellValue(i + 1);

            cell = row.createCell((short) 1);
            cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
            cell.setCellValue(new HSSFRichTextString(""));

            cell = row.createCell((short) 2);
            cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
            if (o.getDelivery() != null) {
                cell.setCellValue(new HSSFRichTextString(o.getDelivery().getReceiver()));
            }

            cell = row.createCell((short) 3);
            cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
            if (o.getDelivery() != null) {
                cell.setCellValue(new HSSFRichTextString(o.getDelivery().getDeliveryPhone()));
            }

            cell = row.createCell((short) 4);
            cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
            cell.setCellValue(new HSSFRichTextString(""));

            cell = row.createCell((short) 5);
            cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
            if (o.getDelivery() != null) {
                cell.setCellValue(new HSSFRichTextString(o.getDelivery().getDeliveryAddress().getAddress()));
            }

            cell = row.createCell((short) 6);
            cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
            if (o.getDelivery() != null) {
                if (o.getDelivery().getSettlementType() != null) {
                    cell.setCellValue(o.getDelivery().getSettlementType().getType());
                }
            }

            cell = row.createCell((short) 7);
            cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
            if (o.getOrderType() == OrderType.FORMULA) {
                cell.setCellValue(new HSSFRichTextString("路远配方产品"));
            }
            else {
                cell.setCellValue(new HSSFRichTextString("路远保健品"));
            }

            cell = row.createCell((short) 8);
            cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
            cell.setCellValue(o.getOrderProducts().size());

            cell = row.createCell((short) 9);
            cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
            cell.setCellValue(1);

            cell = row.createCell((short) 10);
            cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
            cell.setCellValue(new HSSFRichTextString(""));

            cell = row.createCell((short) 11);
            cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
            if (o.getPaymentType() == PaymentType.CASH_ON_DELIVERY) {
                cell.setCellValue(new HSSFRichTextString("Y"));
            }
            else {
                cell.setCellValue(new HSSFRichTextString("N"));
            }

            cell = row.createCell((short) 12);
            cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
            if (o.getPaymentType() == PaymentType.CASH_ON_DELIVERY) {
                cell.setCellValue(o.getAmount());
            }
            else {
                cell.setCellValue(new HSSFRichTextString(""));
            }

            cell = row.createCell((short) 13);
            cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
            cell.setCellValue(new HSSFRichTextString(""));

            cell = row.createCell((short) 14);
            cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
            cell.setCellValue(new HSSFRichTextString(""));

            cell = row.createCell((short) 15);
            cell.setCellStyle(ExcelUtil.getNormalCellStyle(wb));
            cell.setCellValue(new HSSFRichTextString(""));
        }

        synchronized (ExcelUtil.class) {
            ExcelUtil.exportExcel(wb, "销售记录.xls");
        }
    }

    public void exportEMSExcel() throws IOException {
        List<Order> orders = getExportData();

        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet = ExcelUtil.createSheet(wb, "交寄信息");
        sheet.setDisplayGridlines(true);

        String[] headers = { "客户代码", "入网企业代码", "交寄日期", "邮件号", "应收货款", "大写", "支付方式", "保险保价", "保险保价", "收件人", "收件人地址",
                "电话号码", "邮编", "寄出地", "寄达地", "订单号（信用证号）", "货物名称（本行编号）", "备注(公司名字)", "重量", "资费" };
        HSSFRow row = sheet.createRow(0);
        for (short i = 0; i < headers.length; i++) {
            HSSFCell cell = row.createCell(i);
            cell.setCellValue(new HSSFRichTextString(headers[i]));
        }

        int len = orders.size();
        for (int i = 0; i < len; i++) {
            row = sheet.createRow(i + 1);
            Order o = orders.get(i);

            HSSFCell cell = null;

            cell = row.createCell((short) 4);
            cell.setCellValue(new HSSFRichTextString(String.valueOf((int) o.getAmount())));

            cell = row.createCell((short) 5);
            cell.setCellValue(new HSSFRichTextString(getChineseNum((int) o.getAmount())));

            cell = row.createCell((short) 9);
            if (o.getDelivery() != null) {
                cell.setCellValue(new HSSFRichTextString(o.getDelivery().getReceiver()));
            }

            cell = row.createCell((short) 10);
            if (o.getDelivery() != null) {
                cell.setCellValue(new HSSFRichTextString(o.getDelivery().getDeliveryAddress().getAddress()));
            }

            cell = row.createCell((short) 11);
            if (o.getDelivery() != null) {
                cell.setCellValue(new HSSFRichTextString(o.getDelivery().getDeliveryPhone()));
            }

            cell = row.createCell((short) 12);
            if (o.getDelivery() != null) {
                cell.setCellValue(new HSSFRichTextString(o.getDelivery().getDeliveryAddress().getPostCode()));
            }

            cell = row.createCell((short) 13);
            cell.setCellValue(new HSSFRichTextString("福州"));

            cell = row.createCell((short) 14);
            if (o.getDelivery() != null) {
                String province = o.getDelivery().getDeliveryAddress().getProvince();
                String city = o.getDelivery().getDeliveryAddress().getCity();
                if (StringUtils.isNullOrEmpty(city)) {
                    city = CityUtil.getCity(o.getDelivery().getDeliveryAddress().getStreet());
                }

                Region provincialCapital = regionService.findProvincialCapital(province, city);
                if (provincialCapital != null) {
                    cell.setCellValue(new HSSFRichTextString(provincialCapital.getProvincialCapital()));
                }
            }

            cell = row.createCell((short) 16);
            if (o.getOrderType() == OrderType.FORMULA) {
                cell.setCellValue(new HSSFRichTextString("路远产品"));
            }
            else {
                cell.setCellValue(new HSSFRichTextString("路远产品"));
            }

            cell = row.createCell((short) 17);
            cell.setCellValue(new HSSFRichTextString("路远"));
        }

        synchronized (ExcelUtil.class) {
            ExcelUtil.exportExcel(wb, "路远地址库.xls");
        }
    }

    private String getChineseNum(int num) {
        String chineseNum = "";
        for (int i = 10000; i >= 1; i /= 10) {
            if (num - i < 0) {
                chineseNum += "零    ";
                continue;
            }
            switch (num / i) {
            case 0:
                chineseNum += "零    ";
                break;
            case 1:
                chineseNum += "壹    ";
                break;
            case 2:
                chineseNum += "贰    ";
                break;
            case 3:
                chineseNum += "叁    ";
                break;
            case 4:
                chineseNum += "肆    ";
                break;
            case 5:
                chineseNum += "伍    ";
                break;
            case 6:
                chineseNum += "陆    ";
                break;
            case 7:
                chineseNum += "柒    ";
                break;
            case 8:
                chineseNum += "捌    ";
                break;
            case 9:
                chineseNum += "玖    ";
                break;

            default:
                chineseNum += "零    ";
                break;
            }
            num = num - ((num / i) * i);
        }

        return chineseNum;
    }

    @SuppressWarnings("unchecked")
    private List<Order> getExportData() {
        if (orderStatus != OrderStatus.DELIVERED && orderStatus != OrderStatus.VERIFIED) {
            return new ArrayList<Order>();
        }

        CriteriaTemplate c = getCriterialTemplate();

        List<org.hibernate.criterion.Order> orders = new ArrayList<org.hibernate.criterion.Order>();
        orders.add(org.hibernate.criterion.Order.asc("createTime"));
        Page page = orderService.pagedQuery(c, 1, Integer.MAX_VALUE, orders);

        return (List<Order>) page.getResult();
    }

    public Order getOrder() {
        return order;
    }

    public void setOrder(Order order) {
        this.order = order;
    }

    public String getRemarks() {
        return remarks;
    }

    public void setRemarks(String remarks) {
        this.remarks = remarks;
    }

    public ExpressCompany getExpressCompany() {
        return expressCompany;
    }

    public void setExpressCompany(ExpressCompany expressCompany) {
        this.expressCompany = expressCompany;
    }

    public Date getStartDate() {
        return startDate;
    }

    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

    public OrderStatus getOrderStatus() {
        return orderStatus;
    }

    public void setOrderStatus(OrderStatus orderStatus) {
        this.orderStatus = orderStatus;
    }

    public boolean isSingleProduct(Order order) {
        if (order != null) {
            return order.getOrderType() == OrderType.SINGLE_PRODUCT;
        }
        return false;
    }

    public boolean isFormula(Order order) {
        if (order != null) {
            return order.getOrderType() == OrderType.FORMULA;
        }
        return false;
    }

    public String getUuid() {
        return uuid;
    }

    public void setUuid(String uuid) {
        this.uuid = uuid;
    }

    @Override
    public List<SelectItem> getSelectItems(Object... parameters) {
        List<SelectItem> items = new ArrayList<SelectItem>();
        items.add(new SelectItem(OrderStatus.VERIFIED, getI18NMessage("luyuan_crm_sale_order_orderStatus_"
                + OrderStatus.VERIFIED.toString())));
        items.add(new SelectItem(OrderStatus.DELIVERED, getI18NMessage("luyuan_crm_sale_order_orderStatus_"
                + OrderStatus.DELIVERED.toString())));
        return items;
    }
}
